#include <Windows.h>
#include <tchar.h>
#include "resource.h"

void AddTextToEdit(HWND hEdit, TCHAR* szFormat, ...)
{
	va_list vaList;
	va_start(vaList, szFormat);
	TCHAR szContent[1024 * 10];
	GetWindowText(hEdit, szContent, _countof(szContent));
	_vstprintf(_tcschr(szContent, 0), szFormat, vaList);
	SetWindowText(hEdit, szContent);
	va_end(vaList);

	return;
}

BOOL CALLBACK _EnumLangProc(HMODULE hModule, LPCTSTR szType, LPCTSTR szName, WORD wIDLanguage, LONG_PTR lParam)
{
	if (IS_INTRESOURCE(szType))
	{
		AddTextToEdit((HWND)lParam, _T("%24s(%u)\r\n"), _T("|- Language"), wIDLanguage);
	}

	return TRUE;
}

BOOL CALLBACK _EnumNameProc(HMODULE hModule, LPCTSTR szType, LPTSTR szName, LONG_PTR lParam)
{
	if (IS_INTRESOURCE(szType))
	{
		AddTextToEdit((HWND)lParam, _T("%12s(%u)\r\n"), _T("|- Name"), szName);
	}
	EnumResourceLanguages(hModule, szType, szName, _EnumLangProc, lParam);

	return TRUE;
}

BOOL CALLBACK _EnumTypeProc(HMODULE hModule, LPTSTR szType, LONG_PTR lParam)
{
	struct STypeInfo {
		LPWSTR			nID;
		const TCHAR*	szResName;
	};
	STypeInfo ResTypeList[] = { 
		{RT_CURSOR,		_T("CURSOR")},		{RT_BITMAP,			_T("BITMAP")},		{RT_ICON,			_T("ICON")},
		{RT_MENU,		_T("MENU")},		{RT_DIALOG,			_T("DIALOG")},		{RT_STRING,			_T("STRING")},
		{RT_FONTDIR,	_T("FONTDIR")},		{RT_FONT,			_T("FONT")},		{RT_ACCELERATOR,	_T("ACCELERATOR")},
		{RT_RCDATA,		_T("RCDATA")},		{RT_MESSAGETABLE,   _T("MESSAGETABLE")},{RT_GROUP_CURSOR,	_T("GROUP_CURSOR")},
		{RT_GROUP_ICON, _T("GROUP_ICON")},	{RT_VERSION,		_T("VERSION")},		{RT_DLGINCLUDE,		_T("DLGINCLUDE")},
		{RT_PLUGPLAY,   _T("PLUGPLAY")},	{RT_VXD,			_T("VXD")},			{RT_ANICURSOR,		_T("ANICURSOR")},
		{RT_HTML,		_T("HTML")},
	};

	for (int ii = 0; ii < sizeof(ResTypeList)/sizeof(*ResTypeList); ii++)
	{
		if (IS_INTRESOURCE(szType) && (USHORT)ResTypeList[ii].nID == ((USHORT)szType))
		{
			AddTextToEdit((HWND)lParam, _T("\r\n%s\r\n"), ResTypeList[ii].szResName);
		}
	}
	
	EnumResourceNames(hModule, szType, _EnumNameProc, lParam);

	return TRUE;
}

void LoadModule(const TCHAR* szExePath, HWND hEdit)
{
	HMODULE hModule = LoadLibrary(szExePath);
	if (NULL != hModule)
	{
		EnumResourceTypes(hModule, _EnumTypeProc, (LPARAM)hEdit);
	}
	return;
}


int CALLBACK DlgProc(HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	switch (nMsg)
	{
		case WM_INITDIALOG:
		{
			SetWindowText(hDlg, _T("Demo0084"));

			UINT nWidth		= GetSystemMetrics(SM_CXSCREEN);
			UINT nHeight	= GetSystemMetrics(SM_CYSCREEN);
			RECT rtClient;
			GetClientRect(hDlg, &rtClient);
			SetWindowPos(hDlg, NULL, (nWidth - (rtClient.right - rtClient.left)) / 2, (nHeight - (rtClient.bottom - rtClient.top)) / 2, 0, 0, SWP_NOSIZE);
			
			break;
		}
		case WM_DROPFILES:
		{
			HDROP hDrop = (HDROP)wParam;
			TCHAR szPath[MAX_PATH];
			DragQueryFile(hDrop, 0, szPath, MAX_PATH);
			if (0 != _tcslen(szPath) && -1 != GetFileAttributes(szPath))
			{
				SetWindowText(GetDlgItem(hDlg, IDC_STCPATH), szPath);
				SetWindowText(GetDlgItem(hDlg, IDC_EDTINFO), _T(""));
				DragFinish(hDrop);
			}
			
			break;
		}
		case WM_COMMAND:
		{
			switch (LOWORD(wParam))
			{
				case IDC_BTNVIEW:
				{
					TCHAR szModule[MAX_PATH];
					GetDlgItemText(hDlg, IDC_STCPATH, szModule, MAX_PATH);
					SetWindowText(GetDlgItem(hDlg, IDC_EDTINFO), _T(""));
					LoadModule(szModule, GetDlgItem(hDlg, IDC_EDTINFO));

					break;
				}
				case IDC_BTNBROWSE:
				{
					TCHAR szPath[MAX_PATH] = {0};
					OPENFILENAME ofn	= {0};
					ofn.lStructSize		= sizeof(ofn);
					ofn.Flags			= OFN_EXPLORER;
					ofn.hwndOwner		= hDlg;
					ofn.lpstrFilter		= _T("execute file(*.exe)\0*.exe\0");
					ofn.nMaxFile		= MAX_PATH;
					ofn.lpstrFile		= szPath;
					if (GetOpenFileName(&ofn))
					{
						SetWindowText(GetDlgItem(hDlg, IDC_STCPATH), szPath);
					}

					break;
				}
			}
			break;
		}
		case WM_CLOSE:
		{
			PostQuitMessage(0);
			break;
		}
	}

	return 0;
}

BOOL WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPTSTR szCmdLine, int nShowCmd)
{
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);

	return TRUE;
}